package com.example.su_shi_tan_bas_lib.album.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.example.su_shi_tan_bas_lib.R;
import com.example.su_shi_tan_bas_lib.global.AppGlobals;

import java.lang.ref.WeakReference;

import static com.example.library_common.utils.ToastyUtilKt.normalShortToast;

public class CameraBottomView extends View {

    private static final String TAG = CameraBottomView.class.getName();

    private static final int ONLY_CAPTURE_IMG = 0;

    private static final int ONLY_CAPTURE_VIDEO = 1;

    private static final int ONLY_CAPTURE_ALL = 2;

    /**
     * 视频录制最长时间 秒
     */
    private static final int VIDEO_RECORD_DEFAULT_MAX_TIME = 10;
    /**
     * 视频录制最小时间 秒
     */
    private final int VIDEO_RECORD_DEFAULT_MIN_TIME = 1;
    /**
     * 视频录制内圆半径
     */
    private final float VIDEO_RECORD_DEFAULT_INNER_CIRCLE_RADIUS = 5f;
    /**
     * 视频录制外圆半径
     */
    private final float VIDEO_RECORD_DEFAULT_EXCIRCLE_RADIUS = 12f;
    /**
     * 视频录制圆环默认颜色
     */
    private final int VIDEO_RECORD_DEFAULT_ANNULUS_COLOR = Color.parseColor("#FFFFFF");
    /**
     * 视频录制内圆默认颜色
     */
    private final int VIDEO_RECORD_DEFAULT_INNER_CIRCLE_COLOR = Color.parseColor("#F5F5F5");
    /**
     * 视频录制进度默认颜色
     */
    private final int VIDEO_RECORD_DEFAULT_PROGRESS_COLOR = Color.parseColor("#00A653");

    /**
     * 外圆放大倍数
     */
    private final float EXCICLE_MAGNIFICATION = 1.25f;

    private float excicleMagnification;

    /**
     * 内圆缩小倍数
     */
    private final float INNER_CIRCLE_SHRINKS = 0.75f;
    private float innerCircleShrinks;
    /**
     * 视频实际录制最大时间
     */
    private int mMaxTime;
    /**
     * 视频实际录制最小时间
     */
    private int mMinTime;
    /**
     * 外圆半径
     */
    private float mExCircleRadius, mInitExCircleRadius;
    /**
     * 内圆半径
     */
    private float mInnerCircleRadius, mInitInnerRadius;
    /**
     * 外圆颜色
     */
    private int mAnnulusColor;
    /**
     * 内圆颜色
     */
    private int mInnerCircleColor;
    /**
     * 进度条颜色
     */
    private int mProgressColor;
    /**
     * 外圆画笔
     */
    private Paint mExCirclePaint;
    /**
     * 内圆画笔
     */
    private Paint mInnerCirclePaint;
    /**
     * 进度条画笔
     */
    private Paint mProgressPaint;

    /**
     * 是否正在录制
     */
    private boolean isRecording = false;
    /**
     * 进度条值动画
     */
    private ValueAnimator mProgressAni;

    /**
     * 开始录制时间
     */
    private long mStartTime = 0;
    /**
     * 录制 结束时间
     */
    private long mEndTime = 0;
    /**
     * 长按最短时间  单位毫秒
     */
    public long LONG_CLICK_MIN_TIME = 800;
    private Context context;
    private int mWidth;
    private int mHeight;
    private float mCurrentProgress;
    private MHandler handler = new MHandler(this);

    private int captureType = ONLY_CAPTURE_IMG;

    public CameraBottomView(Context context) {
        this(context, null);
    }


    public CameraBottomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraBottomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData(context, attrs);
    }

    /**
     * 获取布局属性
     *
     * @param context
     * @param attrs
     */
    private void initData(Context context, AttributeSet attrs) {
        this.context = context;
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraBottomViewAttrs);
        mMaxTime = a.getInt(R.styleable.CameraBottomViewAttrs_maxTime, VIDEO_RECORD_DEFAULT_MAX_TIME);
        mMinTime = a.getInt(R.styleable.CameraBottomViewAttrs_minTime, VIDEO_RECORD_DEFAULT_MIN_TIME);
        captureType = a.getInt(R.styleable.CameraBottomViewAttrs_click_action, captureType);
        excicleMagnification = a.getFloat(R.styleable.CameraBottomViewAttrs_excicleMagnification
                , EXCICLE_MAGNIFICATION);
        innerCircleShrinks = a.getFloat(R.styleable.CameraBottomViewAttrs_excicleMagnification
                , INNER_CIRCLE_SHRINKS);
        if (excicleMagnification < 1) {
            throw new RuntimeException("外圆放大倍数必须大于1");
        }
        if (innerCircleShrinks > 1) {
            throw new RuntimeException("内圆缩小倍数必须小于1");
        }

        mInitExCircleRadius = mExCircleRadius = a.getDimension(R.styleable.CameraBottomViewAttrs_excircleRadius
                , VIDEO_RECORD_DEFAULT_EXCIRCLE_RADIUS);
        mInitInnerRadius = mInnerCircleRadius = a.getDimension(R.styleable.CameraBottomViewAttrs_innerCircleRadius
                , VIDEO_RECORD_DEFAULT_INNER_CIRCLE_RADIUS);

        mAnnulusColor = a.getColor(R.styleable.CameraBottomViewAttrs_annulusColor
                , VIDEO_RECORD_DEFAULT_ANNULUS_COLOR);
        mInnerCircleColor = a.getColor(R.styleable.CameraBottomViewAttrs_innerCircleColor
                , VIDEO_RECORD_DEFAULT_INNER_CIRCLE_COLOR);
        mProgressColor = a.getColor(R.styleable.CameraBottomViewAttrs_progressColor
                , VIDEO_RECORD_DEFAULT_PROGRESS_COLOR);
        a.recycle();
        //初始化外圆画笔
        mExCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mExCirclePaint.setColor(mAnnulusColor);

        //初始化内圆画笔
        mInnerCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mInnerCirclePaint.setColor(mInnerCircleColor);

        //初始化进度条画笔
        mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mProgressPaint.setColor(mProgressColor);
        mProgressPaint.setStrokeWidth(mExCircleRadius - mInnerCircleRadius);
        mProgressPaint.setStyle(Paint.Style.STROKE);

        //进度条的属性动画
        mProgressAni = ValueAnimator.ofFloat(0, 360f);
        mProgressAni.setDuration(mMaxTime * 1000);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);

        mInitExCircleRadius = mExCircleRadius
                = (mExCircleRadius = Math.min(mWidth, mHeight) >> 1) / excicleMagnification;

        mInitInnerRadius = mInnerCircleRadius = mExCircleRadius * innerCircleShrinks;

        mProgressPaint.setStrokeWidth(mExCircleRadius - mInnerCircleRadius);

//        if (mExCircleRadius * 2 * excicleMagnification > Math.min(mWidth, mHeight)) {
//            throw new RuntimeException("设置的半径的2 * " + excicleMagnification + "倍要小于宽和高中的最小值的");
//        }
//        if (mInnerCircleRadius > mExCircleRadius) {
//            throw new RuntimeException("设置的内圆半径要小于外圆半径");
//        } else if (mInnerCircleRadius == mExCircleRadius) {
//            Log.e(TAG, "mInnerCircleRadius == mExCircleRadius 你将看不到进度条");
//        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float cx = mWidth >> 1, cy = mHeight >> 1;
        //画外圆
        canvas.drawCircle(cx, cy, mExCircleRadius, mExCirclePaint);
        //画内圆
        canvas.drawCircle(cx, cy, mInnerCircleRadius, mInnerCirclePaint);
        if (isRecording) {
            drawProgress(canvas);
        }
    }

    /**
     * 绘制圆形进度条
     * Draw a circular progress bar.
     *
     * @param canvas
     */
    private void drawProgress(Canvas canvas) {

        float strokeWidth = mProgressPaint.getStrokeWidth();

        float ext = mExCircleRadius - strokeWidth / 2;

        //用于定义的圆弧的形状和大小的界限
        RectF oval = new RectF();

        oval.left = (mWidth >> 1) - ext;

        oval.top = (mHeight >> 1) - ext;

        oval.right = (mWidth >> 1) + ext;

        oval.bottom = (mHeight >> 1) + ext;

        //根据进度画圆弧
        canvas.drawArc(oval, -90, mCurrentProgress, false, mProgressPaint);
//        final RectF rectF = new RectF(
//                mWidth / 2 - (mInnerCircleRadius + (mExCircleRadius - mInnerCircleRadius) / 2),
//                mHeight / 2 - (mInnerCircleRadius + (mExCircleRadius - mInnerCircleRadius) / 2),
//                mWidth / 2 + (mInnerCircleRadius + (mExCircleRadius - mInnerCircleRadius) / 2),
//                mHeight / 2 + (mInnerCircleRadius + (mExCircleRadius - mInnerCircleRadius) / 2));
//        canvas.drawArc(rectF, -90, mCurrentProgress, false, mProgressPaint);
    }

    @Override
    public boolean performClick() {
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
//                isRecording = true;
                isRecording = captureType == ONLY_CAPTURE_VIDEO || captureType == ONLY_CAPTURE_ALL;
                mStartTime = System.currentTimeMillis();
                handler.sendEmptyMessageDelayed(MSG_START_LONG_RECORD, LONG_CLICK_MIN_TIME);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isRecording = false;
                mEndTime = System.currentTimeMillis();
                handlerActionUp();
//                if (mEndTime - mStartTime < LONG_CLICK_MIN_TIME) {
//                    //Long press the action time too short.
//                    if (handler.hasMessages(MSG_START_LONG_RECORD)) {
//                        handler.removeMessages(MSG_START_LONG_RECORD);
//                    }
//                    if (onRecordListener != null) {
//                        onRecordListener.onShortClick();
//                    }
//
//                } else {
//
//                    if (mProgressAni != null && mProgressAni.getCurrentPlayTime() / 1000 < mMinTime) {
//                        //The recording time is less than the minimum recording time.
//                        if (onRecordListener != null) {
//                            onRecordListener.OnFinish(0);
//                        }
//                    } else {
//                        //The end of the normal
//                        if (onRecordListener != null) {
//                            onRecordListener.OnFinish(1);
//                        }
//                    }
//                }
//                mExCircleRadius = mInitExCircleRadius;
//                mInnerCircleRadius = mInitInnerRadius;
//                if (mProgressAni != null) {
//                    mProgressAni.cancel();
//                }
//                startAnimation(
//                        mInitExCircleRadius * excicleMagnification,
//                        mInitExCircleRadius,
//                        mInitInnerRadius * innerCircleShrinks,
//                        mInitInnerRadius);
                break;
            case MotionEvent.ACTION_MOVE:
                break;
        }
        return true;
    }

    private void handlerActionUp() {
        switch (captureType) {
            case ONLY_CAPTURE_IMG:

                //Long press the action time too short.
                if (handler.hasMessages(MSG_START_LONG_RECORD)) {
                    handler.removeMessages(MSG_START_LONG_RECORD);
                }
                if (onRecordListener != null) {
                    onRecordListener.onShortClick();
                }
                break;
            case ONLY_CAPTURE_VIDEO:
                if (mEndTime - mStartTime < LONG_CLICK_MIN_TIME) {
                    normalShortToast(AppGlobals.getApplication(),"录制视频太短了");
//                    Toast.makeText(getContext(), "录制视频太短了", Toast.LENGTH_LONG).show();

                } else if (mProgressAni != null
                        && mProgressAni.getCurrentPlayTime() / 1000 < mMinTime
                        && onRecordListener != null) {

                    onRecordListener.OnFinish(0);

                } else if (onRecordListener != null) {
                    onRecordListener.OnFinish(1);
                }
                break;
            case ONLY_CAPTURE_ALL:
                if (mEndTime - mStartTime < LONG_CLICK_MIN_TIME) {
                    //Long press the action time too short.
                    if (handler.hasMessages(MSG_START_LONG_RECORD)) {
                        handler.removeMessages(MSG_START_LONG_RECORD);
                    }
                    if (onRecordListener != null) {
                        onRecordListener.onShortClick();
                    }

                } else {

                    if (mProgressAni != null && mProgressAni.getCurrentPlayTime() / 1000 < mMinTime) {
                        //The recording time is less than the minimum recording time.
                        if (onRecordListener != null) {
                            onRecordListener.OnFinish(0);
                        }
                    } else {
                        //The end of the normal
                        if (onRecordListener != null) {
                            onRecordListener.OnFinish(1);
                        }
                    }
                }
                break;
        }

        mExCircleRadius = mInitExCircleRadius;
        mInnerCircleRadius = mInitInnerRadius;
        if (mProgressAni != null) {
            mProgressAni.cancel();
        }
        startAnimation(
                mInitExCircleRadius / excicleMagnification,
                mInitExCircleRadius,
                mInitInnerRadius * innerCircleShrinks,
                mInitInnerRadius);
    }

    /**
     * 设置外圆 内圆缩放动画
     *
     * @param bigStart
     * @param bigEnd
     * @param smallStart
     * @param smallEnd
     */
    private void startAnimation(float bigStart, float bigEnd, float smallStart, float smallEnd) {
        ValueAnimator bigObjAni = ValueAnimator.ofFloat(bigStart, bigEnd);
        bigObjAni.setDuration(150);
        bigObjAni.addUpdateListener(animation -> {
            mExCircleRadius = (float) animation.getAnimatedValue();
            invalidate();
        });

        ValueAnimator smallObjAni = ValueAnimator.ofFloat(smallStart, smallEnd);
        smallObjAni.setDuration(150);
        smallObjAni.addUpdateListener(animation -> {
            mInnerCircleRadius = (float) animation.getAnimatedValue();
            invalidate();
        });

        bigObjAni.start();
        smallObjAni.start();

        smallObjAni.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //开始绘制圆形进度
                if (isRecording) {
                    startAniProgress();
                }

            }


            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

    }

    /**
     * 开始圆形进度值动画
     */
    private void startAniProgress() {
        if (mProgressAni == null) {
            return;
        }
        mProgressAni.start();
        mProgressAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrentProgress = (float) animation.getAnimatedValue();
                invalidate();
            }
        });

        mProgressAni.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                isRecording = false;
                mCurrentProgress = 0;
                invalidate();
            }
        });
    }

    /**
     * 设置最大录制时间
     *
     * @param mMaxTime 最大录制时间 秒
     */
    public void setMaxTime(int mMaxTime) {
        this.mMaxTime = mMaxTime;
    }

    /**
     * 设置最小录制时间
     *
     * @param mMinTime 最小录制时间 秒
     */
    public void setMinTime(int mMinTime) {
        this.mMinTime = mMinTime;
    }

    /**
     * 设置外圆半径
     *
     * @param mExCircleRadius 外圆半径
     */
    public void setExCircleRadius(float mExCircleRadius) {
        this.mExCircleRadius = mExCircleRadius;
    }

    /**
     * 设置内圆半径
     *
     * @param mInnerCircleRadius 内圆半径
     */
    public void setInnerCircleRadius(float mInnerCircleRadius) {
        this.mInnerCircleRadius = mInnerCircleRadius;
    }

    /**
     * 设置颜色外圆颜色
     *
     * @param mAnnulusColor
     */
    public void setAnnulusColor(int mAnnulusColor) {
        this.mAnnulusColor = mAnnulusColor;
        mExCirclePaint.setColor(mAnnulusColor);
    }

    /**
     * 设置进度圆环颜色
     *
     * @param mProgressColor
     */
    public void setProgressColor(int mProgressColor) {
        this.mProgressColor = mProgressColor;
        mProgressPaint.setColor(mProgressColor);
    }

    /**
     * 设置内圆颜色
     *
     * @param mInnerCircleColor
     */
    public void setInnerCircleColor(int mInnerCircleColor) {
        this.mInnerCircleColor = mInnerCircleColor;
        mInnerCirclePaint.setColor(mInnerCircleColor);
    }

    public void setCaptureImg() {
        this.captureType = ONLY_CAPTURE_IMG;
    }

    public void setOnlyCaptureVideo() {
        this.captureType = ONLY_CAPTURE_VIDEO;
    }

    public void setOnlyCaptureAll() {
        this.captureType = ONLY_CAPTURE_ALL;
    }

    private OnRecordListener onRecordListener;

    public void setOnRecordListener(OnRecordListener onRecordListener) {
        this.onRecordListener = onRecordListener;
    }

    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
        super.setOnClickListener(l);
    }

    public   interface   OnRecordListener {

        /**
         * 点击拍照
         */
         void onShortClick();

        /**
         * 开始录制
         */
         void OnRecordStartClick();

        /**
         * 录制结束
         *
         * @param resultCode 0 录制时间太短 1 正常结束
         */
        void OnFinish(int resultCode);
    }

    /**
     * 长按录制
     */
    private static final int MSG_START_LONG_RECORD = 0x1;


    static class MHandler extends android.os.Handler {

        private WeakReference<CameraBottomView> weakReference = null;

        public MHandler(CameraBottomView controlView) {
            weakReference = new WeakReference<CameraBottomView>(controlView);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (weakReference == null || weakReference.get() == null) return;
            final CameraBottomView videoControlView = weakReference.get();
            switch (msg.what) {
                case CameraBottomView.MSG_START_LONG_RECORD:
                    if (videoControlView.onRecordListener != null) {
                        videoControlView.onRecordListener.OnRecordStartClick();
                    }
                    //内外圆动画，内圆缩小，外圆放大
                    videoControlView.startAnimation(videoControlView.mExCircleRadius,
                            videoControlView.mExCircleRadius * videoControlView.excicleMagnification,
                            videoControlView.mInnerCircleRadius,
                            videoControlView.mInnerCircleRadius * videoControlView.excicleMagnification);
                    break;
            }
        }
    }
}